home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / biged.zip / BIGED.PAS < prev    next >
Pascal/Delphi Source File  |  1990-12-12  |  57KB  |  1,824 lines

  1. {$F+,O+,A+,B-,D-,E+,I-,L-,N-,R-,S-,V-}
  2.  
  3. {***********************************************}
  4. {*              BIGED.PAS  1.03a               *}
  5. {*                (11-Dec-90)                  *}
  6. {*       Copyright (c) Steve Sneed 1990        *}
  7. {*             All rights reserved             *}
  8. {*  Requires ObjectProfessional 1.03 or later  *}
  9. {*           from TurboPower Software          *}
  10. {*                                             *}
  11. {*  Released to TurboPower Software for their  *}
  12. {*               use or release                *}
  13. {***********************************************}
  14.  
  15. {*
  16.     BigEd is a collection of objects for implementing text editors with
  17.     OPro.  "Huh?  OPro already has OpMemo/OpEditor!" you say, and you're
  18.     right.  But for some applications, OpEditor has one crippling
  19.     limitation: it can only handle files of 64K or less in size.  BigEd uses
  20.     a linked list of lines approach to allow files as big as available
  21.     memory.  Because of the gross differences in how the text stream is
  22.     stored and dealt with, BigEd is _not_ a derivitive of OpEditor, rather
  23.     it is a similar-but-different set of objects.
  24.  
  25.     BigEd is modeled very closely on OpEditor as far as public methods and
  26.     calling interface are concerned.  Converting existing applications using
  27.     OpEditor to BigEd is not completely painless, but it is pretty straight-
  28.     forward.  New applications implementing BigEd will closely mirror those
  29.     using OpEditor.  Some things look similar to OpEditor but function
  30.     differently (for example, some of the flags constants in BigEd have the
  31.     same names as those in OpEditor but are used for different things).
  32.  
  33.     BigEd is both more and less than OpEditor.  Some things available in
  34.     OpEditor are not here, either because they didn't really fit (the
  35.     Initxxx routines that used an previously-allocated buffer, for example)
  36.     or because I ran out of time before I got around to 'em.  Streams
  37.     support is noticable by its absense, printer support is limited to that
  38.     provided by the Printer unit that comes with TP, etc.  However, some
  39.     things I've wanted for a while in OpEditor _are_ in BigEd, such as the
  40.     ability to display the current line in a different color (ala QEdit), a
  41.     "Clipboard" that can be copied or cut to and pasted from across multiple
  42.     instances of BigEds or between files within a BigEd instance, and a few
  43.     other geegaws.
  44.  
  45.     A project at work nessessitated this unit, although without some of its
  46.     features as provided here.  A friend wanted it badly, so I'm releasing
  47.     this version now.  It should be considered "rough"; I'm sure there's
  48.     bugs still running loose, several routines could use a good dose of
  49.     optimization, and error-checking is pretty lax in spots (I concentrated
  50.     on out-of-memory and disk-I/O error reporting) but everything here works
  51.     as far as I've tested.  Bug reports, suggestions, complaints and
  52.     requests should be addressed to:
  53.  
  54.     NOTE: This release is untested with the new Version 6.0 of TP and
  55.     version 1.10 of Object Professional.  It _should_ work, but until I
  56.     receive OPro 1.10 I'm not promising.
  57.  
  58.     Steve Sneed
  59.     CompuServe ID# 70007,3574
  60.  
  61.     Permission is hereby given to TurboPower Software to distribute this
  62.     software as they see fit, either on a "Bonus disk" included with their
  63.     products or by making it available on their section of the PCVENB Forum
  64.     on CompuServe.  Private parties may also distribute the software as long
  65.     as no direct charge for such distribution is made.
  66.  
  67.  
  68.     Version History:
  69.     1.03  - Original release.  (*lots* of bugs!)
  70.  
  71.     1.03a - Added support for ccScrollUp/ccScrollDn commands (per Kim's
  72.             request); corrected missing compiler switches and directives in
  73.             BEMAIN; fixed missing update of beModified flag in beTabOver and
  74.             beDeleteWordRight; added EXECACCE.PAS unit with Kim's
  75.             permission; modifed beBreakLine slightly to better conform to
  76.             OpEditor's behavior when blocking ends at the end of a line and
  77.             <CR> is pressed with the cursor beyond the last char in that
  78.             line; fixed bugs in beInsertChar's and beTabOver's handling of
  79.             blocking; tweaked parts of beUpdateContents for slightly better
  80.             performance; fixed a bug in beReformatPara that caused a endless
  81.             loop when reformatting the last paragraph in the file; added
  82.             SetPrinter to match OpEditor's multiple printer port support and
  83.             modified beWriteBlock to match; modified beReadBlock for better
  84.             error checking; corrected logic errors in beLoad; fixed BEMAIN's
  85.             Main proc to not die if the first file loaded had a read error;
  86.             added block case-changing services; fixed a bug in
  87.             beRestoreStreamState that caused the filename in the status line
  88.             to not be updated properly when reloading a previously-loaded
  89.             file; added a couple of missing "change options" methods and the
  90.             "default" Init constructor; removed inadvertly-left-in comment
  91.             marks that prevented BEMAIN's PromptNewFile proc from saving the
  92.             file; other minor cleanups.  (A mess of fixes, true! Shall we
  93.             say, a "recommended upgrade"?)
  94.  
  95. *}
  96.  
  97. unit BigEd;  {"big" editor objects}
  98.  
  99. {$I OPDEFINE.INC}
  100.  
  101. interface
  102.  
  103. uses
  104.   DOS,
  105.   OpDos,
  106.   OpInline,
  107.   OpRoot,
  108.   OpString,
  109.   Lines,
  110.   OpCrt,
  111. {$IFDEF UseMouse}
  112.   OpMouse,
  113. {$ENDIF}
  114.   OpCmd,
  115. {$IFDEF UseDrag}
  116.   OpDrag,
  117. {$ENDIF}
  118.   OpFrame,
  119.   OpWindow;
  120.  
  121. {$I BIGED.ICD}  {keyboard definitions}
  122.  
  123. const
  124.   beInsert         = $00000001;  {True if in insert mode}
  125.   beIndent         = $00000002;  {True if in auto-indent mode}
  126.   beReadOnly       = $00000004;  {True if in read-only mode}
  127.   beWordWrap       = $00000008;  {True if word wrap is on}
  128.   beDeleteJoins    = $00000010;  {True if <Del> can join lines}
  129.   beModified       = $00000020;  {True if edits have been made}
  130.   beIndentIsPara   = $00000040;  {indent starts paragraph?}
  131.   beMousePage      = $00000080;  {clicking on scroll bar scrolls by page}
  132.   beMapCtrls       = $00000200;  {map control characters?}
  133.   beMakeBackups    = $00000400;  {make backup files?}
  134.   beReformatting   = $00001000;  {flag set while reformatting}
  135.   beNewFile        = $00002000;  {new file loaded}
  136.   beWrapAtLeft     = $00008000;  {wrap to prev line on <Left> at column 1}
  137.   beStripHigh      = $00010000;  {strip hi bits when reading a file}
  138.   beNoRepeatGlobal = $00020000;  {flag to not repeat global search}
  139.   beFastScrUpd     = $00040000;  {allow faster kbds/slow video cards}     {!!}
  140.   beBlockOK        = $00080000;  {set if block is currently OK}           {!!}
  141.   beShowMkrs       = $00100000;  {set to display highlighting is searches}
  142.   beInProcess      = $00800000;  {internal flag set while in Process}
  143.   beSmartTabs      = $01000000;  {smart tabs or fixed tabs?}
  144.   beSearching      = $02000000;  {flag set while searching}
  145.   beHighlightOn    = $10000000;  {if set the current line is highlighted} {!!}
  146.   beHighlightBack  = $20000000;  {highlighting goes backwards?}
  147.   beMarkersOn      = $40000000;  {text markers visible?}
  148.   beBlockOn        = $80000000;  {block markers on?}
  149.  
  150.   {the commands in this set are disallowed in read-only mode}
  151.   DisallowedInReadOnlyMode : set of Byte =
  152.    [ccChar, ccCtrlChar, ccSelect, ccInsertLine, ccBack, ccDel, ccRestore,
  153.     ccDelEol, ccDelLine, ccDelWord, ccIns, ccTab, ccIndent, ccWordWrap,
  154.     ccReformatP, ccReformatG];
  155.  
  156.   {default options}
  157.   DefBigEdOptions : LongInt = beInsert+beIndent+beMapCtrls+{beHighlightOn+}
  158.                               beMousePage+beMakeBackups+beSmartTabs;
  159.   BadBigEdOptions : LongInt = beModified+beReformatting+beSearching+beBlockOK+
  160.                               beHighlightBack+beInProcess+beShowMkrs+beNewFile;
  161.   DefEditorExt   : ExtStr = '';   {default file extension}
  162.   MaxBlockIndent = 10;            {maximum indentation level for blocks}
  163.   DefBlockIndent : Byte = 2;      {default indentation level for blocks}
  164.  
  165.   MaxMarker = 3;                  {Maximum allowed position marker}
  166.   MaxSearchLen = 30;              {Maximum length of search string}
  167.  
  168.   {search option characters}
  169.   MaxSearchOptions = 5;
  170.   beBackward  = 'B';
  171.   beNoCase    = 'U';
  172.   beGlobal    = 'G';
  173.   beNoConfirm = 'N';
  174.   beBlockOnly = 'L';
  175.  
  176.   {codes for yes-no functions}
  177.   beNo        = 0;
  178.   beYes       = 1;
  179.   beQuit      = 2;
  180.   beAll       = 3;
  181.  
  182.   beLpt            : Integer = 1;
  183.   beDefTabDelta    : Integer = 8;
  184.   beDefMaxLength   : Integer = 254;
  185.   beWordDelims     : CharSet = [^I, ' '..'"', '.', ',', ':', ';', '?', '!',
  186.                                 '*','(', ')', '[', ']', '{', '}', '<', '>',
  187.                                 '+', '-', '/', '\', '''', '$', '=', '^', '#'];
  188.  
  189. type
  190.   ChArrType = Array[1..$FFF0] of Char;
  191.   ChArrPtr = ^ChArrType;
  192.   CharClass = (Blank, Alpha, Other);
  193.   beSearchType = (bescNone, bescSearch, bescReplace);
  194.  
  195.   BigEdInfoProc = procedure(Msg : String);
  196.   BigEdYesNoFunc = function(MsgCode : Word; Prompt : string;
  197.                             Default : Byte; QuitAndAll : Boolean) : Byte;
  198.   BigEdEditFunc = function(MsgCode : Word; Prompt : string;
  199.                            ForceUp, TrimBlanks : Boolean;
  200.                            MaxLen : Byte; var S : string) : Boolean;
  201.   BigEdGetFileFunc = function(MsgCode : Word; Prompt : string;
  202.                               ForceUp, TrimBlanks, Writing, MustExist : Boolean;
  203.                               MaxLen : Byte; DefExt : ExtStr;
  204.                               var S : string) : Boolean;
  205.  
  206.  
  207.   MarkerRec =                 {used for marking a specific point in the stream}
  208.     record
  209.       Line : LinePtr;
  210.       LNum : Integer;
  211.       Col  : Integer;
  212.     end;
  213.   MarkerArray = Array[0..MaxMarker] of MarkerRec;
  214.  
  215.   StreamStateRec =
  216.     record
  217.       SaveCurTopIdx  : Integer;
  218.       SaveCurLineOfs : Integer;
  219.       SaveXOfs : Integer;
  220.       SaveCOfs : Integer;
  221.       SaveFlags : LongInt;
  222.       SaveBkTop : MarkerRec;
  223.       SaveBkBot : MarkerRec;
  224.       SaveMarkers  : MarkerArray;
  225.     end;
  226.  
  227.   BigEditorPtr = ^BigEditor;
  228.   BigEdStatusProc = procedure(BEP : BigEditorPtr);
  229.   BigEditor =                        {our overall editor object}
  230.     object(CommandWindow)
  231.       EList : LineList;              {current doublelist of lines}
  232.       TmpList : LineList;            {temp list for blocking}
  233.       CurTop : LinePtr;              {current line at top of the window}
  234.       CurLine : LinePtr;             {current line being edited}
  235.       CurTopIdx : Integer;           {line # of CurTop}
  236.       CurLineOfs : Integer;          {# of lines CurLine is down from CurTop}
  237.       XOfs : Integer;                {for horizontal positioning of window}
  238.       COfs : Integer;                {for horizontal positioning of cursor}
  239.       TmpOfs : Integer;              {temp placeholder for positioning}
  240.  
  241.       Current : String;              {current string of text}
  242.       Tmp : String;                  {temp holding string}
  243.  
  244.       Margin : Integer;              {right margin}
  245.       WinWidth : Integer;            {width of inner window}
  246.       WinHeight : Integer;           {height of inner window}
  247.       Path : PathStr;                {name of current file}
  248.       beDefExt : ExtStr;             {default filename extension}
  249.  
  250.       beSearchLine : LinePtr;                {Current line of search}
  251.       beSearchSt : string[MaxSearchLen];     {String to search for}
  252.       beReplaceSt : string[MaxSearchLen];    {String to replace it with}
  253.       beOptionSt : string[MaxSearchOptions]; {Search options}
  254.       beLastSearch : beSearchType;           {Type of last search operation}
  255.       beReplacements : Integer;              {Number of replacements made}
  256.  
  257.       beBlockColor : Byte;                   {attributes for blocks, markers}
  258.       beBlockMono : Byte;                    {and highlighted current line}
  259.       beMarkerColor : Byte;
  260.       beMarkerMono : Byte;
  261.       beHighlightColor : Byte;
  262.       beHighlightMono : Byte;
  263.       beCtrlColor : Byte;
  264.       beCtrlMono : Byte;
  265.       ColorsChanged : Boolean;
  266.  
  267.       beStatusProc : BigEdStatusProc;   {procedure for status}
  268.       beInfoProc : BigEdInfoProc;       {procedure for information}
  269.       beEditFunc : BigEdEditFunc;       {function to edit a string}
  270.       beGetFile : BigEdGetFileFunc;     {function to get a filename}
  271.       beYesNoFunc : BigEdYesNoFunc;     {function to get a Yes/No response}
  272.  
  273.       beOptions : LongInt;           {our current options flags}
  274.       beForceRedraw : Boolean;       {True if we need to redraw the whole window}
  275.       beTabDelta : Integer;          {size of tabs}
  276.       beSaveSize : Integer;          {saved size of list}
  277.  
  278.       BkTop : MarkerRec;             {current marked block top line/col}
  279.       BkBot : MarkerRec;             {current marked block bottom line/col}
  280.       SBkTop : MarkerRec;            {last marked block top line/col}
  281.       SBkBot : MarkerRec;            {last marked block bottom line/col}
  282.       CurPos : MarkerRec;            {saved current position in stream}
  283.       Markers : MarkerArray;         {set of markerrecs for text markers}
  284.       MarkerFlags : Word;            {flag word for set markers}
  285.  
  286.       constructor Init(X1, Y1, X2, Y2 : Byte);
  287.         {-init a BigEditor with default options, allocate new edit list}
  288.       constructor InitCustom(X1, Y1, X2, Y2 : Byte;
  289.                              var Colors : ColorSet;
  290.                              WinOptions : LongInt;
  291.                              EditorOpts : LongInt);
  292.         {-init a BigEditor with custom options, allocate new edit list}
  293.       destructor Done; virtual;
  294.         {-dispose a BigEditor}
  295.       function beOptionsAreOn(L : LongInt) : Boolean;
  296.         {-True if all selected options are on}
  297.       procedure beOptionsOn(L : LongInt);
  298.         {-turn on selected options}
  299.       procedure beOptionsOff(L : LongInt);
  300.         {-turn off selected options}
  301.       {...}
  302.       procedure beSetInfoProc(IP : BigEdInfoProc);
  303.         {-set the procedure for beInfo}
  304.       procedure beSetStatusProc(SP : BigEdStatusProc);
  305.         {-set the procedure for beStatus}
  306.       procedure beSetEditProc(EF : BigEdEditFunc);
  307.         {-Set edit function}
  308.       procedure beSetGetFileProc(GFF : BigEdGetFileFunc);
  309.         {-Set get file function}
  310.       procedure beSetYesNoProc(YNF : BigEdYesNoFunc);
  311.         {-Set yes-no function}
  312.       procedure beSetTextAttr(Color, Mono : Byte);
  313.         {-set attributes for normal text}
  314.       procedure beSetBlockAttr(Color, Mono : Byte);
  315.         {-Set attributes for marked blocks}
  316.       procedure beSetMarkerAttr(Color, Mono : Byte);
  317.         {-Set attributes for text markers and found text}
  318.       procedure beSetHighlightAttr(Color, Mono : Byte);
  319.         {-Set attributes for highlighted current line}
  320.       procedure beSetCtrlAttr(Color, Mono : Byte);
  321.         {-Set attributes for mapped control characters}
  322.       procedure SetBlockIndent(Indent : Byte);
  323.         {-Set block indentation level}
  324.       procedure SetDefaultExtension(DefExt : ExtStr);
  325.         {-Default extension to use when prompting for filenames}
  326.       procedure SetPrinter(LptNum : Integer);
  327.         {-Set printer (1-3)}
  328.       {...}
  329.  
  330.         {**methods that exist to be overridden**}
  331.       procedure beInformation(MsgCode : Word; Msg : String); virtual;
  332.         {-display info}
  333.       function beGetString(MsgCode : Word; Prompt : string;
  334.                            ForceUp, TrimBlanks : Boolean;
  335.                            MaxLen : Byte; var S : string) : Boolean; virtual;
  336.         {-get an input string}
  337.       function beGetNumber(MsgCode : Word; Prompt : string;
  338.                            var L : LongInt; LLo, LHi : LongInt) : Boolean; virtual;
  339.         {-get an input number}
  340.       function beYesNo(MsgCode : Word; Prompt : string; Default : Byte;
  341.                        QuitAndAll : Boolean) : Byte; virtual;
  342.         {-get a Yes/No response}
  343.       function beGetFileName(MsgCode : Word; Prompt : string;
  344.                              var FName : PathStr;
  345.                              Writing : Boolean;
  346.                              MustExist : Boolean) : Boolean; virtual;
  347.         {-get a filename}
  348.       procedure NewFilePrompted; virtual;
  349.         {-prompt for a new file and load it}
  350.       procedure UpdateContents; virtual;
  351.         {-object-level screen update}
  352.       procedure ProcessSelf; virtual;
  353.         {-main process loop}
  354.  
  355.         {*** internal methods ***}
  356.       procedure beResetMarkers(ClearTextMarkers : Boolean);
  357.       procedure beResetLineList;
  358.       procedure beNewLineList;
  359.       procedure beSaveThisPosition;
  360.       procedure beCursorRight(Count : Integer);
  361.       procedure beCursorLeft(Count : Integer);
  362.       procedure beCursorHome;
  363.       procedure beCursorEOL;
  364.       procedure beTopOfFile;
  365.       procedure beEndOfFile;
  366.       procedure beScrollUp(Count : Integer);
  367.       procedure beScrollDown(Count : Integer);
  368.       procedure beLineUp(Count : Integer);
  369.       procedure beLineDown(Count : Integer);
  370.       procedure beJumpToLine(I : Integer);
  371.       procedure beJumpToLinePtr(P : LinePtr);
  372.       procedure beResetSplit;
  373.       procedure beRealign;
  374.       procedure beRealignDown;
  375.       function  beOfsWhite(P : LinePtr) : Byte;
  376.       procedure beClearBlocking;
  377.       procedure beConnectMarks;
  378.       procedure beCheckBlock;
  379.       function  beLineInBlock(P : LinePtr) : Boolean;
  380.       procedure beSetBkTop;
  381.       procedure beSetBkBot;
  382.       function  beStoreBlock(var ToList : LineList) : Boolean;
  383.       procedure beInsertBlockAtCursor(var FromList : LineList);
  384.       procedure beCopyBlock;
  385.       procedure beMoveBlock;
  386.       procedure beReadBlock;
  387.       procedure beWriteBlock(ToPrn : Boolean);
  388.       procedure beDeleteBlock;
  389.       procedure beIndentBlock(AddSP : Boolean);
  390.       procedure beBlockWord;
  391.       procedure beChangeCaseBlock(Cmd : Byte);
  392.       procedure beCopyToClipboard;
  393.       procedure beCutToClipboard;
  394.       procedure bePasteFromClipboard;
  395.       procedure beDeleteLinePrim(P : LinePtr);
  396.       procedure beCharsInserted(LP : LinePtr; Count : Integer);
  397.       procedure beLineDeleted(P : LinePtr);
  398.       procedure beBreakLine(At : Integer);
  399.       procedure beWrapLine;
  400.       procedure beJoinLines(LP : LinePtr);
  401.       procedure beTabOver;
  402.       procedure beInsertChar(C : Char);
  403.       procedure beNewLine(MoveDown : Boolean);
  404.       procedure beBackspace;
  405.       procedure beDeleteCharAtCursor;
  406.       procedure beWordLeft;
  407.       procedure beWordRight;
  408.       procedure beDeleteWordRight;
  409.       procedure beDeleteToEndOfLine;
  410.       procedure beCenterLine;
  411.       procedure beSaveStreamState(var S : StreamStateRec;
  412.                                   SaveBlocking : Boolean);
  413.       procedure beRestoreStreamState(var S : StreamStateRec;
  414.                                      RestoreBlocking : Boolean);
  415.       procedure beTextSearch(Prompt : Boolean; SearchType : beSearchType);
  416.       procedure beReformatPara;
  417.       procedure beReformatGlobally;
  418.  
  419.       function beLoad(FN : String; MustExist : Boolean) : Boolean;
  420.       function beStore(FN : String) : Boolean;
  421.       {$IFDEF UseScrollBars}
  422.       procedure beUpdateScrollBars;
  423.       {$ENDIF}
  424.       procedure beUpdateContents;
  425.       procedure ProcessCtrlChar;
  426.       {$IFDEF UseMouse}
  427.       function beProcessMouseCommand : Boolean;
  428.       {$ENDIF}
  429.       procedure beSetRightMarginPrompted;
  430.       procedure beSetBlockIndentPrompted;
  431.       procedure beSetTabSizePrompted;
  432.     end;
  433.  
  434.  
  435. var
  436.   Clipboard : LineList;
  437.  
  438. {$IFDEF UseDrag}
  439.   BigEdCommands : DragProcessor;
  440. {$ELSE}
  441.   BigEdCommands : CommandProcessor;
  442. {$ENDIF}
  443.  
  444. implementation
  445.  
  446. {globals used in TextSearches}
  447. var
  448.   NoCase : Boolean;
  449.   Backwards : Boolean;
  450.   NoConfirm : Boolean;
  451.   BlockOnly : Boolean;
  452.   Global : Boolean;
  453.  
  454.   function Min(A,B : Integer) : Integer;
  455.   begin
  456.     if A < B then
  457.       Min := A
  458.     else
  459.       Min := B;
  460.   end;
  461.  
  462.   procedure StripHiBits(var S : String);
  463.   var B : Byte;
  464.   begin
  465.     for B := 1 to Length(S) do
  466.       S[b] := Char(Byte(S[b]) and $7F);
  467.   end;
  468.  
  469.   function GetClass(Ch : Char) : CharClass;
  470.   begin
  471.     if Ch = ' ' then
  472.       GetClass := Blank
  473.     else if Ch in beWordDelims then
  474.       GetClass := Other
  475.     else
  476.       GetClass := Alpha;
  477.   end;
  478.  
  479.   procedure IncPtr(var LP : LinePtr; Count : Integer);
  480.   var I : Integer;
  481.   begin
  482.     for I := 1 to Count do
  483.       if LP <> NIL then
  484.         LP := LinePtr(LP^.dlNext);
  485.   end;
  486.  
  487.   procedure DecPtr(var LP : LinePtr; Count : Integer);
  488.   var I : Integer;
  489.   begin
  490.     for I := 1 to Count do
  491.       if LP <> NIL then
  492.         LP := LinePtr(LP^.dlPrev);
  493.   end;
  494.  
  495. {---------------------------------------------------------------------------}
  496.  
  497.   constructor BigEditor.Init(X1, Y1, X2, Y2 : Byte);
  498.   begin
  499.     if NOT BigEditor.InitCustom(X1, Y1, X2, Y2, DefaultColorSet,
  500.                                 DefWindowOptions, DefBigEdOptions) then
  501.       Fail;
  502.   end;
  503.  
  504.   constructor BigEditor.InitCustom(X1, Y1, X2, Y2 : Byte;
  505.                                    var Colors : ColorSet;
  506.                                    WinOptions : LongInt;
  507.                                    EditorOpts : LongInt);
  508.   begin
  509.     if NOT CommandWindow.InitCustom(X1, Y1, X2, Y2, Colors, WinOptions,
  510.                                     BigEdCommands, ucNone) then begin
  511.       WriteLn('Error ',InitStatus,' initing CommandWindow');
  512.       Fail;
  513.     end;
  514.  
  515.     EList.Init;
  516.     TmpList.Init;
  517.  
  518.     beNewLineList;
  519.  
  520.     beSearchLine := NIL;
  521.     beSearchSt := '';
  522.     beReplaceSt := '';
  523.     beOptionSt := '';
  524.     WinWidth := Width;
  525.     Margin := Width - 2;
  526.     beForceRedraw := True;
  527.     beSaveSize := $7FFF;
  528.     beOptions := EditorOpts;
  529.     beTabDelta := beDefTabDelta;
  530.     Path := '';
  531.     beDefExt := DefEditorExt;
  532.  
  533.     with Colors do begin
  534.       beBlockColor := BlockColor;
  535.       beBlockMono := BlockMono;
  536.       beMarkerColor := MarkerColor;
  537.       beMarkerMono := MarkerMono;
  538.       beHighlightColor := HighlightColor;
  539.       beHighlightMono := HighlightMono;
  540.       beCtrlColor := CtrlColor;
  541.       beCtrlMono := CtrlMono;
  542.       ColorsChanged := True;
  543.     end;
  544.  
  545.     @beStatusProc := NIL;
  546.     @beInfoProc := NIL;
  547.     @beEditFunc := NIL;
  548.     @beGetFile := NIL;
  549.     @beYesNoFunc := NIL;
  550.   end;
  551.  
  552.  
  553.   destructor BigEditor.Done;
  554.   begin
  555.     TmpList.Done;
  556.     EList.Done;
  557.     CommandWindow.Done;
  558.   end;
  559.  
  560.   function BigEditor.beOptionsAreOn(L : LongInt) : Boolean;
  561.     {-True if all selected options are on}
  562.   begin
  563.     beOptionsAreOn := (LongFlagIsSet(beOptions,L));
  564.   end;
  565.  
  566.   procedure BigEditor.beOptionsOn(L : LongInt);
  567.     {-turn on one or more options}
  568.   begin
  569.     SetLongFlag(beOptions,L and not BadBigEdOptions);
  570.   end;
  571.  
  572.   procedure BigEditor.beOptionsOff(L : LongInt);
  573.     {-turn off one or more options}
  574.   begin
  575.     ClearLongFlag(beOptions,L or BadBigEdOptions);
  576.   end;
  577.  
  578.   procedure BigEditor.beSetInfoProc(IP : BigEdInfoProc);
  579.     {-assign the "information" procedure}
  580.   begin
  581.     beInfoProc := IP;
  582.   end;
  583.  
  584.   procedure BigEditor.beSetStatusProc(SP : BigEdStatusProc);
  585.     {-assign the "status" procedure}
  586.   begin
  587.     beStatusProc := SP;
  588.   end;
  589.  
  590.   procedure BigEditor.beSetEditProc(EF : BigEdEditFunc);
  591.     {-assign the line editor service}
  592.   begin
  593.     beEditFunc := EF;
  594.   end;
  595.  
  596.   procedure BigEditor.beSetGetFileProc(GFF : BigEdGetFileFunc);
  597.     {-assign the service to get a file name}
  598.   begin
  599.     beGetFile := GFF;
  600.   end;
  601.  
  602.   procedure BigEditor.beSetYesNoProc(YNF : BigEdYesNoFunc);
  603.     {-assign the service to get a yes/no response}
  604.   begin
  605.     beYesNoFunc := YNF;
  606.   end;
  607.  
  608.   procedure BigEditor.beSetTextAttr(Color, Mono : Byte);
  609.     {-change the default attribute for marked blocks}
  610.   begin
  611.     wTextColor := Color;
  612.     wTextMono := MapMono(Color, Mono);
  613.     ColorsChanged := True;
  614.   end;
  615.  
  616.   procedure BigEditor.beSetBlockAttr(Color, Mono : Byte);
  617.     {-change the default attribute for marked blocks}
  618.   begin
  619.     beBlockColor := Color;
  620.     beBlockMono := MapMono(Color, Mono);
  621.     ColorsChanged := True;
  622.   end;
  623.  
  624.   procedure BigEditor.beSetMarkerAttr(Color, Mono : Byte);
  625.     {-change the default attribute for text markers}
  626.   begin
  627.     beMarkerColor := Color;
  628.     beMarkerMono := MapMono(Color, Mono);
  629.     ColorsChanged := True;
  630.   end;
  631.  
  632.   procedure BigEditor.beSetHighlightAttr(Color, Mono : Byte);
  633.     {-change the default attribute for highlighting the current line}
  634.   begin
  635.     beHighlightColor := Color;
  636.     beHighlightMono := MapMono(Color, Mono);
  637.     ColorsChanged := True;
  638.   end;
  639.  
  640.   procedure BigEditor.beSetCtrlAttr(Color, Mono : Byte);
  641.     {-change the default attribute for mapped control characters}
  642.   begin
  643.     beCtrlColor := Color;
  644.     beCtrlMono := MapMono(Color, Mono);
  645.     ColorsChanged := True;
  646.   end;
  647.  
  648.   procedure BigEditor.beInformation(MsgCode: Word; Msg : String);
  649.     {-overridable method for info}
  650.   begin
  651.     if @beInfoProc <> nil then
  652.       beInfoProc(Msg);
  653.   end;
  654.  
  655.   function BigEditor.beGetString(MsgCode : Word; Prompt : string;
  656.                                  ForceUp, TrimBlanks : Boolean;
  657.                                  MaxLen : Byte; var S : string) : Boolean;
  658.     {-overridable method for GetString}
  659.   begin
  660.     if cwCmdPtr^.CommandStringPending then begin
  661.       S := cwCmdPtr^.GetCommandString;
  662.       beGetString := True;
  663.     end
  664.     else if @beEditFunc = nil then
  665.       beGetString := False
  666.     else
  667.       beGetString := beEditFunc(MsgCode, Prompt, ForceUp, TrimBlanks, MaxLen, S);
  668.   end;
  669.  
  670.   function BigEditor.beGetNumber(MsgCode : Word; Prompt : string;
  671.                                  var L : LongInt; LLo, LHi : LongInt) : Boolean;
  672.     {-overridable method for GetNumber}
  673.   var
  674.     OK : Boolean;
  675.     St : String[10];
  676.     LT : LongInt;
  677.   begin
  678.     beGetNumber := False;
  679.     LT := L;
  680.     St := Long2Str(LT);
  681.  
  682.     repeat
  683.       if (not beGetString(MsgCode, Prompt, False, True, 10, St)) or (St = '') then
  684.         Exit;
  685.       OK := Str2Long(St, LT) and (LT >= LLo) and (LT <= LHi);
  686.       if not OK then
  687.         GotError(epWarning+ecInvalidNumber, emInvalidNumber);
  688.     until OK;
  689.  
  690.     L := LT;
  691.     beGetNumber := True;
  692.   end;
  693.  
  694.   function BigEditor.beYesNo(MsgCode : Word; Prompt : string; Default : Byte;
  695.                              QuitAndAll : Boolean) : Byte;
  696.     {-overridable method for getting a yes/no response}
  697.   var
  698.     S : string[1];
  699.   begin
  700.     if cwCmdPtr^.CommandStringPending then begin
  701.       S := cwCmdPtr^.GetCommandString;
  702.       beYesNo := Default;
  703.       if S <> '' then
  704.         case S[1] of
  705.           'N' : beYesNo := beNo;
  706.           'Y' : beYesNo := beYes;
  707.           'Q' : beYesNo := beQuit;
  708.           'A' : beYesNo := beAll;
  709.         end;
  710.     end
  711.     else if @beYesNoFunc = nil then
  712.       beYesNo := beQuit
  713.     else
  714.       beYesNo := beYesNoFunc(MsgCode, Prompt, Default, QuitAndAll);
  715.   end;
  716.  
  717.   function BigEditor.beGetFileName(MsgCode : Word; Prompt : string;
  718.                                    var FName : PathStr;
  719.                                    Writing : Boolean;
  720.                                    MustExist : Boolean) : Boolean;
  721.     {-overridable method for getting a filename}
  722.   const
  723.     MaxLen = SizeOf(PathStr)-1;
  724.   begin
  725.     if cwCmdPtr^.CommandStringPending then begin
  726.       FName := DefaultExtension(cwCmdPtr^.GetCommandString, beDefExt);
  727.       beGetFileName := (FName <> '');
  728.     end
  729.     else if @beGetFile = nil then
  730.       beGetFileName := False
  731.     else if beGetFile(MsgCode, Prompt, True, True, Writing, MustExist,
  732.                       MaxLen, beDefExt, FName) then begin
  733.       {FName := DefaultExtension(FName, beDefExt);} {!!.01}
  734.       beGetFileName := (FName <> '');
  735.     end
  736.     else
  737.       beGetFileName := False;
  738.   end;
  739.  
  740. {---------------------------------------------------------------------------}
  741.  
  742.   procedure BigEditor.beResetMarkers(ClearTextMarkers : Boolean);
  743.   begin
  744.     FillChar(BkTop,SizeOf(BkTop),0);
  745.     BkBot := BkTop;
  746.     if ClearTextMarkers then begin
  747.       FillChar(Markers,SizeOf(Markers),0);
  748.       MarkerFlags := 0;
  749.     end;
  750.   end;
  751.  
  752.   procedure BigEditor.beResetLineList;
  753.   begin
  754.     with EList do begin
  755.       CurTop := LinePtr(dlHead);
  756.       CurLine := CurTop;
  757.       CurTopIdx := 1;
  758.       CurLineOfs := 0;
  759.       COfs := 1;
  760.       XOfs := 0;
  761.       Current := CurTop^.lnReturn;
  762.       beResetMarkers(True);
  763.       beSaveThisPosition;
  764.     end;
  765.   end;
  766.  
  767.   procedure BigEditor.beNewLineList;
  768.   var L : LinePtr;
  769.   begin
  770.     New(L,Init(''));
  771.     EList.Clean;
  772.     EList.Append(L);
  773.     beResetLineList;
  774.   end;
  775.  
  776.   procedure BigEditor.beSaveThisPosition;
  777.   begin
  778.     with CurPos do begin
  779.       Line := CurLine;
  780.       LNum := CurTopIdx+CurLineOfs;
  781.       Col  := COfs+XOfs;
  782.     end;
  783.   end;
  784.  
  785.   procedure BigEditor.beCursorRight(Count : Integer);
  786.   var N : Integer;
  787.   begin
  788.     for N := 1 to Count do begin
  789.       if XOfs + Width >= 254 then
  790.         exit;
  791.       if COfs < Width then
  792.         Inc(COfs)
  793.       else begin
  794.         Inc(XOfs);
  795.         beForceRedraw := True;
  796.       end;
  797.     end;
  798.   end;
  799.  
  800.   procedure BigEditor.beCursorLeft(Count : Integer);
  801.   var N : Integer;
  802.   begin
  803.     for N := 1 to Count do
  804.       if COfs > 1 then
  805.         Dec(COfs)
  806.       else if XOfs > 0 then begin
  807.         Dec(XOfs);
  808.         beForceRedraw := True;
  809.       end
  810.       else if (Count = 1) and (beOptionsAreOn(beWrapAtLeft)) then begin
  811.         beLineUp(1);
  812.         beCursorEOL;
  813.       end;
  814.   end;
  815.  
  816.   procedure BigEditor.beCursorHome;
  817.   begin
  818.     COfs := 1;
  819.     if XOfs > 0 then
  820.       beForceRedraw := True;
  821.     XOfs := 0;
  822.   end;
  823.  
  824.   procedure BigEditor.beCursorEOL;
  825.   var N : Integer;
  826.   begin
  827.     beCursorHome;
  828.     beCursorRight(CurLine^.lnLen);
  829.   end;
  830.  
  831.   procedure BigEditor.beTopOfFile;
  832.   begin
  833.     CurTop := LinePtr(EList.dlHead);
  834.     CurLine := CurTop;
  835.     CurTopIdx := 1;
  836.     CurLineOfs := 0;
  837.     COfs := 1;
  838.     XOfs := 0;
  839.     beForceRedraw := True;
  840.   end;
  841.  
  842.   procedure BigEditor.beEndOfFile;
  843.   var
  844.     N : Integer;
  845.   begin
  846.     CurTop := LinePtr(EList.dlTail);
  847.     CurLine := CurTop;
  848.     CurTopIdx := EList.Size;
  849.     CurLineOfs := 0;
  850.     for N := 1 to Height-1 do
  851.       if CurTop^.dlPrev <> nil then begin
  852.         CurTop := LinePtr(CurTop^.dlPrev);
  853.         Dec(CurTopIdx);
  854.         Inc(CurLineOfs);
  855.       end;
  856.     beForceRedraw := True;
  857.   end;
  858.  
  859.   procedure BigEditor.beScrollUp(Count : Integer);
  860.   var
  861.     N : Integer;
  862.   begin
  863.     for N := 1 to Count do
  864.       if CurTop^.dlPrev <> nil then begin
  865.         CurTop := LinePtr(CurTop^.dlPrev);
  866.         Dec(CurTopIdx);
  867.         CurLine := LinePtr(CurLine^.dlPrev);
  868.       end;
  869.     beForceRedraw := True;
  870.   end;
  871.  
  872.   procedure BigEditor.beScrollDown(Count : Integer);
  873.   var
  874.     N : Integer;
  875.   begin
  876.     for N := 1 to Count do
  877.       if CurTop^.dlNext <> nil then begin
  878.         CurTop := LinePtr(CurTop^.dlNext);
  879.         Inc(CurTopIdx);
  880.         if CurLine^.dlNext <> nil then
  881.           CurLine := LinePtr(CurLine^.dlNext)
  882.         else if CurLineOfs > 0 then
  883.           Dec(CurLineOfs)
  884.         else
  885.           CurLine := CurTop;
  886.       end;
  887.     beForceRedraw := True;
  888.   end;
  889.  
  890.   procedure BigEditor.beLineUp(Count : Integer);
  891.   var
  892.     N : Integer;
  893.   begin
  894.     N := 0;
  895.     while N < Count do
  896.       if CurLineOfs = 0 then begin
  897.         beScrollUp(Count - N);
  898.         exit;
  899.       end
  900.       else begin
  901.         CurLine := LinePtr(CurLine^.dlPrev);
  902.         Dec(CurLineOfs);
  903.         Inc(N);
  904.       end;
  905.   end;
  906.  
  907.   procedure BigEditor.beLineDown(Count : Integer);
  908.   var
  909.     N : Integer;
  910.   begin
  911.     N := 0;
  912.     while N < Count do
  913.       if CurLineOfs = (Height - 1) then begin
  914.         beScrollDown(Count - N);
  915.         exit;
  916.       end
  917.       else begin
  918.         if CurLine^.dlNext <> nil then begin
  919.           CurLine := LinePtr(CurLine^.dlNext);
  920.           Inc(CurLineOfs);
  921.         end;
  922.         Inc(N);
  923.       end;
  924.   end;
  925.  
  926.   procedure BigEditor.beJumpToLine(I : Integer);
  927.   begin
  928.     CurTop := LinePtr(EList.Nth(I));
  929.     CurTopIdx := I;
  930.     CurLine := CurTop;
  931.     CurLineOfs := 0;
  932.     while (CurLineOfs < Height div 2) and (CurTop^.dlPrev <> nil) do begin
  933.       CurTop := LinePtr(CurTop^.dlPrev);
  934.       Dec(CurTopIdx);
  935.       Inc(CurLineOfs);
  936.     end;
  937.   end;
  938.  
  939.   procedure BigEditor.beJumpToLinePtr(P : LinePtr);
  940.   begin
  941.     CurTop := P;
  942.     CurTopIdx := EList.Num(P);
  943.     CurLine := CurTop;
  944.     CurLineOfs := 0;
  945.     while (CurLineOfs < Height div 2) and (CurTop^.dlPrev <> nil) do begin
  946.       CurTop := LinePtr(CurTop^.dlPrev);
  947.       Dec(CurTopIdx);
  948.       Inc(CurLineOfs);
  949.     end;
  950.   end;
  951.  
  952. {$I BIGED.IN1}
  953.  
  954.   function BigEditor.beLoad(FN : String; MustExist : Boolean) : Boolean;
  955.     {-load a text stream for editing}
  956.   label ExitPoint;
  957.   var F : Text;
  958.       P : LinePtr;
  959.       A : String;
  960.       R : ChArrPtr;
  961.       RSiz : Integer;
  962.       L : LongInt;
  963.   begin
  964.     beNewLineList;
  965.     with EList do begin
  966.         {if possible, make a TextBuf to speed things up}
  967.       L := MaxAvail;
  968.       if L >= $4000 then
  969.         RSiz := $4000
  970.       else if L > 4096 then
  971.         RSiz := Word(L)
  972.       else
  973.         RSiz := 0;
  974.       if RSiz > 0 then
  975.         GetMem(R,RSiz);
  976.       beLoad := False;
  977.  
  978.         {load the file}
  979.       SetLongFlag(beOptions,beNewFile);
  980.       Assign(F,FN);
  981.       if RSiz > 0 then SetTextBuf(F,R^,RSiz);
  982.       Reset(F);
  983.       if (IOResult = 0) then begin
  984.         beInformation(0,'Loading '+FN+'...');
  985.         while NOT EOF(F) do begin
  986.           ReadLn(F,A);
  987.           if IOResult <> 0 then begin
  988.             Close(F);  if IOResult = 0 then ;
  989.             GotError(epNonFatal+ecDeviceRead,'Error reading '+FN);
  990.             goto ExitPoint;
  991.           end;
  992.           A := TrimTrail(A);
  993.           if beOptionsAreOn(beStripHigh) then
  994.             StripHiBits(A);
  995.           New(P,Init(A));
  996.           if P = NIL then begin
  997.             GotError(epFatal+ecOutofMemory,'Out of memory');
  998.             goto ExitPoint;
  999.           end;
  1000.           PlaceBefore(P,Tail);
  1001.         end;
  1002.         Close(F);  if IOResult = 0 then ;
  1003.       end
  1004.       else if MustExist then begin
  1005.         GotError(epNonFatal+ecFileNotFound,FN+' not found');
  1006.         goto ExitPoint;
  1007.       end;
  1008.       Path := StUpCase(FN);
  1009.       beLoad := True;
  1010.     end;
  1011.     beResetLineList;
  1012. ExitPoint:
  1013.     if RSiz > 0 then
  1014.       FreeMem(R,RSiz);
  1015.     beInformation(0,'');
  1016.     beForceRedraw := True;
  1017.   end;
  1018.  
  1019.   function BigEditor.beStore(FN : String) : Boolean;
  1020.     {-save the current stream to a file}
  1021.   label Skip;
  1022.   var F : Text;
  1023.       P : LinePtr;
  1024.       B : Boolean;
  1025.       D : Boolean;
  1026.       R : ChArrPtr;
  1027.       RSiz : Integer;
  1028.       L : LongInt;
  1029.  
  1030.     function MakeABackup : Boolean;
  1031.       {-make a backup copy of the file}
  1032.     var G : File;
  1033.     begin
  1034.       MakeABackup := False;
  1035.       if ExistFile(ForceExtension(FN,'BAK')) then begin
  1036.         Assign(G,ForceExtension(FN,'BAK'));
  1037.         System.Erase(G);
  1038.         if IOResult <> 0 then exit;
  1039.       end;
  1040.       Assign(G,FN);
  1041.       Rename(G,ForceExtension(FN,'BAK'));
  1042.       if IOResult <> 0 then exit;
  1043.       MakeABackup := True;
  1044.     end;
  1045.  
  1046.   begin
  1047.     with EList do begin
  1048.       beStore := False;
  1049.       if LongFlagIsSet(beOptions,beMakeBackups) then
  1050.         if NOT MakeABackUp then exit;
  1051.  
  1052.         {if possible, make a TextBuf to speed things up}
  1053.       L := MaxAvail;
  1054.       if L >= $4000 then
  1055.         RSiz := $4000
  1056.       else if L > 4096 then
  1057.         RSiz := Word(L)
  1058.       else
  1059.         RSiz := 0;
  1060.  
  1061.       Assign(F,FN);
  1062.       if RSiz > 0 then begin
  1063.         GetMem(R,RSiz);
  1064.         SetTextBuf(F,R^,RSiz);
  1065.       end;
  1066.       Rewrite(F);
  1067.       if IOResult <> 0 then
  1068.         goto Skip;
  1069.  
  1070.       beInformation(0,'Saving '+FN+'...');
  1071.       P := LinePtr(dlHead);
  1072.       while (P <> NIL) and (P <> LinePtr(Tail)) do begin
  1073.         WriteLn(F,P^.lnReturn);
  1074.         if IOResult <> 0 then goto Skip;
  1075.         P := LinePtr(P^.dlNext);
  1076.       end;
  1077.       beStore := True;
  1078. Skip:
  1079.       Close(F);  if IOResult = 0 then ;
  1080.       if RSiz > 0 then
  1081.         FreeMem(R,RSiz);
  1082.       beInformation(0,'');
  1083.     end;
  1084.   end;
  1085.  
  1086.   {$IFDEF UseScrollBars}
  1087.   procedure BigEditor.beUpdateScrollBars;
  1088.     {-Update horizontal and vertical scroll bars}
  1089.   begin
  1090.     if EList.Size <> beSaveSize then begin
  1091.       ChangeAllScrollBars(0, (254-Width), 1, EList.Size);
  1092.       beSaveSize := EList.Size;
  1093.     end;
  1094.     DrawAllSliders(XOfs, CurTopIdx+CurLineOfs);
  1095.   end;
  1096.   {$ENDIF}
  1097.  
  1098.   procedure BigEditor.beUpdateContents;
  1099.     {-low-level screen update routine}
  1100.   label Skip;
  1101.   const
  1102.     TAttr : Byte = $07;
  1103.     HAttr : Byte = $0F;
  1104.     BAttr : Byte = $70;
  1105.     MAttr : Byte = $09;
  1106.     CAttr : Byte = $70;
  1107.   var
  1108.     P : LinePtr;
  1109.     N : Integer;
  1110.     MY : Byte;
  1111.  
  1112.     procedure DrawLine(P : LinePtr; Y : Byte);
  1113.       {-draw one line of the window, accounting for all possible qwerks}
  1114.     var I  : Integer;
  1115.         St : String;
  1116.         As : String;
  1117.         S  : String[MaxSearchLen];
  1118.         L  : Byte;
  1119.         J,K : Integer;
  1120.         M  : Boolean;
  1121.         MB : Boolean;
  1122.     begin
  1123.       with EList do begin
  1124.         L := P^.lnLen;
  1125.  
  1126.           {set up the basic line}
  1127.         FillChar(St[1],WinWidth,' ');
  1128.         St[0] := Chr(WinWidth);
  1129.         if (P <> NIL) and (L > XOfs) then
  1130.           MoveFast(P^.St^[XOfs+1],St[1],Min(L-XOfs,Width));
  1131.         if (P = CurLine) and (LongFlagIsSet(beOptions,beHighlightOn)) then
  1132.           FillChar(As[1],WinWidth,Chr(HAttr))
  1133.         else
  1134.           FillChar(As[1],WinWidth,Chr(TAttr));
  1135.         As[0] := Chr(WinWidth);
  1136.  
  1137.         if P <> NIL then begin
  1138.             {handle blocking}
  1139.           if (P^.lnFlagsAreOn(IsBlocked)) and
  1140.              (LongFlagIsSet(beOptions,beBlockOn)) then begin
  1141.             if P = BkTop.Line then begin
  1142.               K := 0;  J := 1;
  1143.               if P = BkBot.Line then begin
  1144.                 if BkTop.Col <= XOfs then
  1145.                   J := 1
  1146.                 else
  1147.                   J := BkTop.Col - XOfs;
  1148.                 if LongInt((BkBot.Col + 1) - J) < 1 then
  1149.                   K := 0
  1150.                 else if (BkBot.Col + 1) - J > WinWidth then
  1151.                   K := WinWidth
  1152.                 else
  1153.                   K := (BkBot.Col + 1) - J;
  1154.               end
  1155.               else if BkTop.Col <= XOfs then begin
  1156.                 J := 1;
  1157.                 K := WinWidth;
  1158.               end
  1159.               else if BkTop.Col > WinWidth then
  1160.                 K := 0
  1161.               else begin
  1162.                 J := BkTop.Col - XOfs;
  1163.                 K := WinWidth - J + 1;
  1164.               end;
  1165.               if K > 0 then
  1166.                 FillChar(As[J],K,Chr(BAttr));
  1167.             end
  1168.             else if P = BkBot.Line then begin
  1169.               if BkBot.Col > XOfs+WinWidth then
  1170.                 FillChar(As[1],WinWidth,Chr(BAttr))
  1171.               else if BkBot.Col > XOfs then
  1172.                 FillChar(As[1],BkBot.Col-XOfs,Chr(BAttr));
  1173.             end
  1174.             else
  1175.               FillChar(As[1],WinWidth,Chr(BAttr));
  1176.           end;
  1177.  
  1178.             {handle markers}
  1179.           if (LongFlagIsSet(beOptions,beMarkersOn)) then
  1180.             for I := 0 to MaxMarker do
  1181.               if P = Markers[i].Line then
  1182.                 if (Markers[i].Col >= XOfs) and (Markers[i].Col <= (XOfs+WinWidth)) then begin
  1183.                   St[Markers[i].Col-XOfs+1] := Chr(Ord('0')+i);
  1184.                   As[Markers[i].Col-XOfs+1] := Chr(MAttr);
  1185.                 end;
  1186.  
  1187.           if (P = beSearchLine) and
  1188.              (beOptionsAreOn(beSearching)) and
  1189.              (beOptionsAreOn(beShowMkrs)) then begin
  1190.             if LongFlagIsSet(beOptions,beHighlightBack) then
  1191.               FillChar(As[COfs-Byte(beSearchSt[0])],Byte(beSearchSt[0]),MAttr)
  1192.             else
  1193.               FillChar(As[COfs],Byte(beSearchSt[0]),MAttr);
  1194.           end;
  1195.  
  1196.             {map controls}
  1197.           if LongFlagIsSet(beOptions,beMapCtrls) then
  1198.             for I := 1 to Length(St) do
  1199.               if St[i] < #32 then begin
  1200.                 Inc(Byte(St[i]),64);
  1201.                 As[i] := Char(CAttr);
  1202.               end;
  1203.         end;
  1204.  
  1205. {$IFDEF UseMouse}
  1206.         if MY = (Y+wYL) then begin
  1207.           HideMousePrim(M);
  1208.           MB := True;
  1209.         end
  1210.         else MB := False;
  1211. {$ENDIF}
  1212.         FastWriteAttr(St, Y+wYL, wXL, As);
  1213. {$IFDEF UseMouse}
  1214.         if MB then ShowMousePrim(M);
  1215. {$ENDIF}
  1216.       end;
  1217.     end;
  1218.  
  1219.   begin
  1220.       {see if we need to update the colors}
  1221.     if ColorsChanged then begin
  1222.       TAttr := ColorMono(wTextColor,wTextMono);
  1223.       HAttr := ColorMono(beHighlightColor,beHighlightMono);
  1224.       BAttr := ColorMono(beBlockColor,beBlockMono);
  1225.       CAttr := ColorMono(beCtrlColor,beCtrlMono);
  1226.       MAttr := ColorMono(beMarkerColor,beMarkerMono);
  1227.       ColorsChanged := False;
  1228.     end;
  1229.  
  1230.     with EList do begin
  1231. {$IFDEF UseMouse}
  1232.       MY := MouseWhereY;
  1233. {$ENDIF}
  1234.       WinHeight := Height - 1;
  1235.       WinWidth := Width;
  1236.  
  1237.       if beForceRedraw then begin
  1238.         P := CurTop;
  1239.         for N := 0 to WinHeight do begin
  1240.           DrawLine(P,N);
  1241.           if cwCmdPtr^.cpKeyPressed then
  1242.             goto Skip;
  1243.           if P <> NIL then
  1244.             P := LinePtr(P^.dlNext);
  1245.         end;
  1246.           {don't reset beForceRedraw until here, so if we drop out before  }
  1247.           {redrawing the whole screen we'll be sure to attempt it next time}
  1248.         beForceRedraw := False;
  1249.       end
  1250.       else begin
  1251.         DrawLine(CurLine,CurLineOfs);
  1252.         if LongFlagIsSet(beOptions,beHighlightOn) then begin
  1253.             {keep highlighting current}
  1254.           if CurLineOfs > 0 then
  1255.             DrawLine(LinePtr(CurLine^.dlPrev),CurLineOfs-1);
  1256.           if CurLineOfs < (Height-1) then
  1257.             DrawLine(LinePtr(CurLine^.dlNext),CurLineOfs+1);
  1258.         end;
  1259.       end;
  1260. Skip:
  1261.         {position and fixup cursor, scrollbars, status}
  1262. {$IFDEF UseScrollBars}
  1263.       beUpdateScrollBars;
  1264. {$ENDIF}
  1265.       GoToXYAbs(Pred(wXL)+COfs,wYL+CurLineOfs);
  1266.       if LongFlagIsSet(beOptions,beInsert) then FatCursor else NormalCursor;
  1267.         {make sure status line is updated}
  1268.       beStatusProc(@Self);
  1269.     end;
  1270.   end;
  1271.  
  1272.   procedure BigEditor.UpdateContents;
  1273.     {-object-level redraw}
  1274.   begin
  1275.     CommandWindow.UpdateContents;
  1276.     beUpdateContents;
  1277.   end;
  1278.  
  1279.   procedure BigEditor.ProcessCtrlChar;
  1280.     {-process ^P request}
  1281.   var Ch : Char absolute cwKey;
  1282.   begin
  1283.     if ColorMono(wTextColor, wTextMono) = ColorMono(beCtrlColor, beCtrlMono) then
  1284.       cwCmd := ccNone
  1285.     else begin
  1286.       BlockCursor;
  1287.       cwKey := cwCmdPtr^.cpGetKey;
  1288.       case Ch of
  1289.         ^M : cwCmd := ccSelect;
  1290.     ^J, ^Z : cwCmd := ccNone;
  1291.         else cwCmd := ccChar;
  1292.       end;
  1293.       if LongFlagIsSet(beOptions,beInsert) then FatCursor else NormalCursor;
  1294.     end;
  1295.   end;
  1296.  
  1297.   {$IFDEF UseMouse}
  1298.   function BigEditor.beProcessMouseCommand : Boolean;
  1299.     {-Process ccMouseSel command. Returns True to return control to user.}
  1300.   var
  1301.     L : LongInt;
  1302.     FramePos : FramePosType;
  1303.     HotCode : Byte;
  1304.  
  1305.     procedure CurLineToNewOfs;
  1306.     var P : LinePtr;
  1307.         W : Integer;
  1308.     begin
  1309.       CurLine := CurTop;
  1310.       W := 0;
  1311.       while W <> CurLineOfs do begin
  1312.         CurLine := LinePtr(EList.Next(CurLine));
  1313.         Inc(W);
  1314.       end;
  1315.     end;
  1316.  
  1317.     procedure MouseSelect;
  1318.       {-Move cursor to position of mouse}
  1319.     var
  1320.       CurRow, TargetLine : Integer;
  1321.       TargetRow, TargetCol, I : Integer;
  1322.     begin
  1323.       CurLineOfs := MouseKeyWordY+MouseYLo-wYL;
  1324.       COfs := MouseKeyWordX+MouseXLo-(wXL-1);
  1325.       CurLineToNewOfs;
  1326.       beForceRedraw := True;
  1327.     end;
  1328.  
  1329.   begin
  1330.     beProcessMouseCommand := False;
  1331.  
  1332.     {determine position of mouse}
  1333.     EvaluateMousePos;
  1334.     L := PosResults(FramePos, HotCode);
  1335.  
  1336.     case HotCode of
  1337.       hsNone :           {not a hot spot}
  1338.         case FramePos of
  1339.           frInsideActive :       {inside window}
  1340.             MouseSelect;
  1341.  
  1342.           frTL..frRR,            {on the frame}
  1343.           frInsideFrame,         {inside window frame but not in window boundaries}
  1344.           frOutsideFrame :       {outside window frame}
  1345.             beProcessMouseCommand := LongFlagIsSet(wFlags, wAllMouseEvents);
  1346.         end;
  1347.  
  1348.       {$IFDEF UseScrollBars}
  1349.       hsDecV :            {the decrement fixture of a vertical scroll bar}
  1350.         if LongFlagIsSet(beOptions, beMousePage) then
  1351.           beScrollUp(Height - 1)
  1352.         else if (CurTopIdx = 1) and (CurLineOfs > 0) then
  1353.           beTopOfFile
  1354.         else
  1355.           beScrollUp(1);
  1356.       hsDecH :           {the decrement fixture of a horizontal scroll bar}
  1357.         if XOfs > 0 then begin
  1358.           Dec(XOfs);
  1359.           beForceRedraw := True;
  1360.         end;
  1361.       hsIncV :           {the increment fixture of a vertical scroll bar}
  1362.         if LongFlagIsSet(beOptions, beMousePage) then
  1363.           beScrollDown(Height - 1)
  1364.         else
  1365.           beScrollDown(1);
  1366.       hsIncH :           {the increment fixture of a horizontal scroll bar}
  1367.         if XOfs < (255 - WinWidth) then begin
  1368.           Inc(XOfs);
  1369.           beForceRedraw := True;
  1370.         end;
  1371.       hsBar :            {the slider portion of a scroll bar}
  1372.         case FramePos of
  1373.           frLL, frRR :   {vertical scroll bar}
  1374.             begin
  1375.               L := TweakSlider(FramePos, MouseKeyWordY+MouseYLo, L, 1);
  1376.               if L <= 1 then
  1377.                 {goto top of file}
  1378.                 beTopOfFile
  1379.               else begin
  1380.                 if L >= EList.Size then
  1381.                   {goto end of file}
  1382.                   beEndOfFile
  1383.                 else
  1384.                   {goto specified line}
  1385.                   beJumpToLine(Word(L));
  1386.               end;
  1387.             end;
  1388.           else begin     {horizontal scroll bar}
  1389.             XOfs := Word(TweakSlider(FramePos, MouseKeyWordX+MouseXLo, L, 1));
  1390.             beForceRedraw := True;
  1391.           end;
  1392.         end;
  1393.       {$ENDIF}
  1394.  
  1395.       hsSpot,            {a single character hot spot}
  1396.       hsRegion0..255 :   {a user-defined region relative to a frame}
  1397.         beProcessMouseCommand := True;
  1398.     end;
  1399.  
  1400.   end;
  1401.   {$ENDIF}
  1402.  
  1403.   procedure BigEditor.NewFilePrompted;
  1404.     {-prompt for a new file}
  1405.   var TmpS : String;
  1406.       B : Byte;
  1407.       W : Integer;
  1408.   begin
  1409.     if LongFlagIsSet(beOptions,beModified) then begin
  1410.       B := beYesNo(0, 'File modified.  Save it?', beYes, False);
  1411.       if (B = beYes) and (Path <> '') then
  1412.         if beStore(Path) then ;
  1413.     end;
  1414.     TmpS := Path;
  1415.     if (beGetFileName(0,'New file: ',TmpS,False,False)) and
  1416.        (StUpCase(TmpS) <> Path) then begin
  1417.       TmpS := DefaultExtension(TmpS,'PAS');
  1418.       beInformation(0,'Working...');
  1419.       if NOT beLoad(TmpS,False) then begin
  1420.         GotError(epFatal+ecDeviceRead,'Error loading new file');
  1421.         SetLastCommand(ccError);
  1422.       end
  1423.       else ClearLongFlag(beOptions,beModified);
  1424.     end;
  1425.     beForceRedraw := True;
  1426.     beInformation(0,'');
  1427.   end;
  1428.  
  1429.   procedure BigEditor.beSetRightMarginPrompted;
  1430.     {-Prompt for a new right margin}
  1431.   var
  1432.     TMargin : LongInt;
  1433.   begin
  1434.     TMargin := Margin;
  1435.     if beGetNumber(epMessage+mcRightMargin, emRightMargin, TMargin, 1, 127) then
  1436.       Margin := TMargin;
  1437.   end;
  1438.  
  1439.   procedure BigEditor.SetBlockIndent(Indent : Byte);
  1440.     {-Set block indentation level}
  1441.   begin
  1442.     if Indent > MaxBlockIndent then
  1443.       DefBlockIndent := MaxBlockIndent
  1444.     else if Indent > 0 then
  1445.       DefBlockIndent := Indent;
  1446.   end;
  1447.  
  1448.   procedure BigEditor.SetDefaultExtension(DefExt : ExtStr);
  1449.     {-Default extension to use when prompting for filenames}
  1450.   begin
  1451.     beDefExt := DefExt;
  1452.   end;
  1453.  
  1454.   procedure BigEditor.SetPrinter(LptNum : Integer);
  1455.   begin
  1456.     if (LptNum < 1) or (LptNum > 3) then exit;
  1457.     beLpt := LptNum;
  1458.   end;
  1459.  
  1460.   procedure BigEditor.beSetBlockIndentPrompted;
  1461.     {-Prompt for a new block indentation level}
  1462.   var
  1463.     Indent : LongInt;
  1464.   begin
  1465.     Indent := DefBlockIndent;
  1466.     if beGetNumber(epMessage+mcIndentLevel, emIndentLevel, Indent, 1, MaxBlockIndent) then
  1467.       DefBlockIndent := Indent;
  1468.   end;
  1469.  
  1470.   procedure BigEditor.beSetTabSizePrompted;
  1471.     {-Prompt for a new tab size}
  1472.   var
  1473.     TabSize : LongInt;
  1474.   begin
  1475.     TabSize := beTabDelta;
  1476.     if beGetNumber(epMessage+mcTabSize, emTabSize, TabSize, 1, 10) then
  1477.       beTabDelta := TabSize;
  1478.   end;
  1479.  
  1480.  
  1481.   procedure BigEditor.ProcessSelf;
  1482.        {-main process loop}
  1483.   var ProcessDone : Boolean;
  1484.       W,N,X : Integer;
  1485.       L : LinePtr;
  1486.       LI : LongInt;
  1487.       B : Byte;
  1488.       TmpS : PathStr;
  1489.   begin
  1490.     Draw;
  1491.     W := RawError;
  1492.     if W <> 0 then begin
  1493.       FastWrite(Pad('Fatal Error '+Long2Str(W),ScreenWidth),1,1,$4F);
  1494.       halt;
  1495.     end;
  1496.     ShowMouse;
  1497.     ProcessDone := False;
  1498.     SetLongFlag(beOptions,beInProcess);
  1499.     with EList do repeat
  1500.       beUpdateContents;
  1501.       cwCmd := cwCmdPtr^.GetCommand(cwKey);
  1502.  
  1503.       if LongFlagIsSet(beOptions,beReadOnly) then
  1504.         if cwCmd in DisallowedInReadOnlyMode then begin
  1505.           cwCmd := ccNone;
  1506.         end;
  1507.  
  1508.       if cwCmd = ccCtrlChar then
  1509.         ProcessCtrlChar;
  1510.  
  1511.       Current := CurLine^.lnReturn;
  1512.       case cwCmd of
  1513.         ccMouseSel :
  1514.           ProcessDone := beProcessMouseCommand;
  1515.  
  1516.         ccChar :
  1517.           beInsertChar(Chr(Lo(cwKey)));
  1518.  
  1519.         ccSelect :
  1520.           beNewLine(True);
  1521.  
  1522.         ccBlkBegin :
  1523.           beSetBkTop;
  1524.  
  1525.         ccBlkEnd :
  1526.           beSetBkBot;
  1527.  
  1528.         ccSetMark0..ccSetMark9 :
  1529.           begin
  1530.             Markers[cwCmd-60].Line := CurLine;
  1531.             Markers[cwCmd-60].LNum := CurTopIdx+CurLineOfs;
  1532.             Markers[cwCmd-60].Col := COfs+XOfs-1;
  1533.             SetLongFlag(beOptions,beMarkersOn);
  1534.             SetFlag(MarkerFlags,1 shl (cwCmd - 60));
  1535.             beForceRedraw := True;
  1536.           end;
  1537.  
  1538.         ccJmpMark0..ccJmpMark9 :
  1539.           if Markers[cwCmd-70].Line <> NIL then begin
  1540.             beJumpToLinePtr(Markers[cwCmd-70].Line);
  1541.             XOfs := 0;
  1542.             COfs := 1;
  1543.             beCursorRight(Markers[cwCmd-70].Col);
  1544.           end;
  1545.  
  1546.         ccInsertLine :
  1547.           beNewLine(False);
  1548.  
  1549.         ccBack :
  1550.           beBackspace;
  1551.  
  1552.         ccDelLine :
  1553.           begin
  1554.             beDeleteLinePrim(CurLine);
  1555.             beCursorHome;
  1556.             beForceRedraw := True;
  1557.           end;
  1558.  
  1559.         ccDel :
  1560.           beDeleteCharAtCursor;
  1561.  
  1562.         ccDelWord :
  1563.           beDeleteWordRight;
  1564.  
  1565.         ccDelEol :
  1566.           beDeleteToEndOfLine;
  1567.  
  1568.         ccUp :
  1569.           beLineUp(1);
  1570.  
  1571.         ccDown :
  1572.           beLineDown(1);
  1573.  
  1574.         ccPageUp :
  1575.           if CurTopIdx = 1 then
  1576.             beTopOfFile
  1577.           else
  1578.             beScrollUp(Height - 1);
  1579.  
  1580.         ccPageDn :
  1581.           beScrollDown(Height - 1);
  1582.  
  1583.         ccScrollUp :
  1584.           beScrollUp(1);
  1585.  
  1586.         ccScrollDn :
  1587.           beScrollDown(1);
  1588.  
  1589.         ccScreenTop :
  1590.           begin
  1591.             CurLine := CurTop;
  1592.             CurLineOfs := 0;
  1593.           end;
  1594.  
  1595.         ccScreenBot :
  1596.           begin
  1597.             CurLine := CurTop;
  1598.             CurLineOfs := 0;
  1599.             beLineDown(Height);
  1600.           end;
  1601.  
  1602.         ccTopOfFile :
  1603.           beTopOfFile;
  1604.  
  1605.         ccEndOfFile :
  1606.           beEndOfFile;
  1607.  
  1608.         ccJmpLine :
  1609.           begin
  1610.             LI := LongInt(CurTopIdx + CurLineOfs);
  1611.             if beGetNumber(0,'Jump to line: ',LI,1,EList.Size) then begin
  1612.               beJumpToLine(LI);
  1613.               beForceRedraw := True;
  1614.             end;
  1615.           end;
  1616.  
  1617.         ccTabSize :
  1618.           beSetTabSizePrompted;
  1619.  
  1620.         ccTab :
  1621.           beTabOver;
  1622.  
  1623.         ccLeft :
  1624.           beCursorLeft(1);
  1625.  
  1626.         ccRight :
  1627.           beCursorRight(1);
  1628.  
  1629.         ccHome :
  1630.           beCursorHome;
  1631.  
  1632.         ccEnd :
  1633.           beCursorEOL;
  1634.  
  1635.         ccWordLeft :
  1636.           beWordLeft;
  1637.  
  1638.         ccWordRight :
  1639.           beWordRight;
  1640.  
  1641.         ccMarkToggle :
  1642.           begin
  1643.             if LongFlagIsSet(beOptions,beMarkersOn) then
  1644.               ClearLongFlag(beOptions,beMarkersOn)
  1645.             else
  1646.               SetLongFlag(beOptions,beMarkersOn);
  1647.             beForceRedraw := True;
  1648.           end;
  1649.  
  1650.         ccTabToggle :
  1651.           if LongFlagIsSet(beOptions,beSmartTabs) then
  1652.             ClearLongFlag(beOptions,beSmartTabs)
  1653.           else
  1654.             SetLongFlag(beOptions,beSmartTabs);
  1655.  
  1656.         ccIns :
  1657.           if LongFlagIsSet(beOptions,beInsert) then
  1658.             ClearLongFlag(beOptions,beInsert)
  1659.           else
  1660.             SetLongFlag(beOptions,beInsert);
  1661.  
  1662.         ccIndent :
  1663.           if LongFlagIsSet(beOptions,beIndent) then
  1664.             ClearLongFlag(beOptions,beIndent)
  1665.           else
  1666.             SetLongFlag(beOptions,beIndent);
  1667.  
  1668.         ccRtMargin :
  1669.           beSetRightMarginPrompted;
  1670.  
  1671.         ccCenterLine :
  1672.           if beOptionsAreOn(beWordWrap) then
  1673.             beCenterLine;
  1674.  
  1675.         ccWordWrap :
  1676.           if LongFlagIsSet(beOptions,beWordWrap) then
  1677.             ClearLongFlag(beOptions,beWordWrap)
  1678.           else
  1679.             SetLongFlag(beOptions,beWordWrap);
  1680.  
  1681.         ccBlkToggle :
  1682.           begin
  1683.             if LongFlagIsSet(beOptions,beBlockOn) then
  1684.               ClearLongFlag(beOptions,beBlockOn)
  1685.             else
  1686.               SetLongFlag(beOptions,beBlockOn);
  1687.             beForceRedraw := True;
  1688.           end;
  1689.  
  1690.         ccBlkCopy :
  1691.           beCopyBlock;
  1692.  
  1693.         ccBlkMove :
  1694.           beMoveBlock;
  1695.  
  1696.         ccBlkDelete :
  1697.           beDeleteBlock;
  1698.  
  1699.         ccBlkUCase,
  1700.         ccBlkLCase,
  1701.         ccBlkTCase :
  1702.           beChangeCaseBlock(cwCmd);
  1703.  
  1704.         ccSetIndent :
  1705.           beSetBlockIndentPrompted;
  1706.  
  1707.         ccBlkIndent :
  1708.           beIndentBlock(True);
  1709.  
  1710.         ccBlkUnindent :
  1711.           beIndentBlock(False);
  1712.  
  1713.         ccBlkRead :
  1714.           beReadBlock;
  1715.  
  1716.         ccBlkWord :
  1717.           beBlockWord;
  1718.  
  1719.         ccJmpBegin :
  1720.           begin
  1721.             if NOT(beOptionsAreOn(beBlockOn)) or
  1722.                NOT(beOptionsAreOn(beBlockOK)) then
  1723.               GotError(epNonFatal+ecNoBlock,'No block defined')
  1724.             else begin
  1725.               beJumpToLinePtr(BkTop.Line);
  1726.               beCursorHome;
  1727.               beCursorRight(BkTop.Col-1);
  1728.             end;
  1729.           end;
  1730.  
  1731.         ccJmpEnd :
  1732.           begin
  1733.             if NOT(beOptionsAreOn(beBlockOn)) or
  1734.                NOT(beOptionsAreOn(beBlockOK)) then
  1735.               GotError(epNonFatal+ecNoBlock,'No block defined')
  1736.             else begin
  1737.               beJumpToLinePtr(BkBot.Line);
  1738.               beCursorHome;
  1739.               beCursorRight(BkBot.Col);
  1740.             end;
  1741.           end;
  1742.  
  1743.         ccBlkWrite :
  1744.           beWriteBlock(False);
  1745.  
  1746.         ccBlkPrint :
  1747.           beWriteBlock(True);
  1748.  
  1749.         ccCopy :
  1750.           beCopyToClipboard;
  1751.  
  1752.         ccCut :
  1753.           beCutToClipboard;
  1754.  
  1755.         ccPaste :
  1756.           bePasteFromClipboard;
  1757.  
  1758.         ccSearch :
  1759.           beTextSearch(True, bescSearch);
  1760.  
  1761.         ccReplace :
  1762.           beTextSearch(True, bescReplace);
  1763.  
  1764.         ccReSearch :
  1765.           beTextSearch(False, bescSearch);
  1766.  
  1767.         ccReformatP :
  1768.           beReformatPara;
  1769.  
  1770.         ccReformatG :
  1771.           beReformatGlobally;
  1772.  
  1773.         ccNewFile :
  1774.           NewFilePrompted;
  1775.  
  1776.         ccAbandonFile :
  1777.           ProcessDone := True;
  1778.  
  1779.         ccSaveNamed :
  1780.           begin
  1781.             TmpS := Path;
  1782.             if (beGetFileName(0,'Save file as: ',TmpS,False,False)) and
  1783.                (TmpS <> '') then begin
  1784.               TmpS := DefaultExtension(TmpS,'PAS');
  1785.               beInformation(0,'Working...');
  1786.               if not beStore(TmpS) then
  1787.                 GotError(epNonFatal+ecDeviceWrite,'Error loading new file')
  1788.               else
  1789.                 ClearLongFlag(beOptions,beModified);
  1790.             end;
  1791.           end;
  1792.  
  1793.         ccSaveFile :
  1794.           if Path <> '' then
  1795.             if beStore(Path) then
  1796.               ClearLongFlag(beOptions,beModified);
  1797.  
  1798.         ccSaveSwitch :
  1799.           begin
  1800.             if Path <> '' then
  1801.               if beStore(Path) then
  1802.                 ClearLongFlag(beOptions,beModified);
  1803.             NewFilePrompted;
  1804.           end;
  1805.  
  1806.         ccUser0..ccUser65335,
  1807.         ccQuit,
  1808.         ccError :
  1809.           ProcessDone := True;
  1810.  
  1811.         else ;
  1812.       end;
  1813.     until ProcessDone;
  1814.     ClearLongFlag(beOptions,beInProcess);
  1815.     HideMouse;
  1816.     rwSaveWindowState;
  1817.   end;
  1818.  
  1819. begin
  1820.   if NOT BigEdCommands.Init(@BigEdKeySet,BigEdKeyMax) then Halt;
  1821.   Clipboard.Init;
  1822. end.
  1823.  
  1824.